package com.star.message.utils;

import com.star.common.core.contract.enums.ResultCodeEnum;
import com.star.common.core.contract.exception.ServiceException;
import com.star.message.repository.model.UserEmailConfigBO;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.util.HtmlUtils;

import java.io.File;
import java.util.Properties;
import java.util.Set;

/**
 * email 工具类
 *
 * @author zhouhengzhe
 * @version 1.0
 * @date 2023/6/16 14:53
 */
@Slf4j
public class EmailUtils {

    private final JavaMailSender javaMailSender;

    private final String username;


    public EmailUtils(UserEmailConfigBO userEmailConfigBO) {
        this.javaMailSender = javaMailSender(userEmailConfigBO);
        username = userEmailConfigBO.getSendAddress();
    }

    protected JavaMailSender javaMailSender(UserEmailConfigBO userEmailConfigBO) {
        JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
        javaMailSenderImpl.setHost(userEmailConfigBO.getSmtpHost());
        javaMailSenderImpl.setUsername(userEmailConfigBO.getSendAddress());
        javaMailSenderImpl.setPassword(userEmailConfigBO.getSendPassword());
        javaMailSenderImpl.setPort(25);
        javaMailSenderImpl.setDefaultEncoding("UTF-8");
        Properties props = new Properties();
        props.setProperty("spring.mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("spring.mail.smtp.socketFactory.fallback", "false");
        //设置端口
        //启用调试
        props.setProperty("mail.debug", "true");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
        javaMailSenderImpl.setJavaMailProperties(props);
        return javaMailSenderImpl;
    }

    /**
     * 发送邮件（可以单个，可以多个人）
     *
     * @param from    发送者,别名 userEmailConfigBO.getPersonal()
     * @param to      收件人  自定义
     * @param cc      抄送人 自定义
     * @param subject 邮件主题  userEmailConfigBO.getSubject()
     * @param content 邮件内容 userEmailConfigBO.getContent()
     */
    public void sendSimpleMail(String from, Set<String> to, String cc, String subject, String content) {
        try {
            //简单邮件
            SimpleMailMessage simpleMessage = new SimpleMailMessage();
            simpleMessage.setFrom(aliasFrom(from));
            simpleMessage.setTo(to.toArray(new String[0]));
            if (StringUtils.isNotBlank(cc)) {
                simpleMessage.setCc(cc);
            }
            simpleMessage.setSubject(subject);
            simpleMessage.setText(content);
            //发送邮件
            javaMailSender.send(simpleMessage);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 设置别名
     *
     * @param personal 发送方，别名
     * @return 别名
     */
    private String aliasFrom(String personal) {
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotBlank(personal)) {
            sb.append(personal).append('<').append(username).append('>');
        } else {
            sb.append(username);
        }
        return sb.toString();
    }


    /**
     * 发送带附件的邮件
     *
     * @param from    发送者
     * @param to      收件人
     * @param cc      抄送人
     * @param subject 邮件主题
     * @param content 邮件内容
     * @param file    发送的文件
     */
    public void sendAttachFileMail(String from, String to, String cc, String subject, String content, File file) {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(aliasFrom(from));
            helper.setTo(to);
            helper.setCc(cc);
            helper.setSubject(subject);
            helper.setText(content);
            helper.addAttachment(file.getName(), file);
            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 发送带图片的邮件
     *
     * @param from    发送者
     * @param to      收件人
     * @param subject 邮件主题
     * @param content 邮件内容
     * @param srcPath 图片资源路径
     * @param resIds  资源id
     */
    public void sendMailWithImg(String from, String to, String subject, String content, String[] srcPath, String[] resIds) {
        if (srcPath.length != resIds.length) {
            throw new ServiceException(ResultCodeEnum.EMAIL_TEMPLATE_RESOURCE_ID_NOT_MATCH);
        }
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(aliasFrom(from));
            helper.setTo(to);
            helper.setSubject(subject);
            //默认false,设置为true表示邮件正文是html格式。
            helper.setText(content, true);
            for (int i = 0; i < srcPath.length; i++) {
                FileSystemResource res = new FileSystemResource(new File(srcPath[i]));
                helper.addInline(resIds[i], res);
            }
            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /**
     * 构建请求体
     *
     * @param domainUrl 域名
     * @param logoUrl   logo
     * @param code      验证码
     * @param content   内容
     *                  <p>如下
     *        <div>      <img         src=&{logoUrl}        alt=""        width=""        height=""      />     <div style="text-align: center; font-size: 20px">        你的验证码是:     </div>      <div style="text-align: center; margin-top: 4px; margin-bottom: 20px">        <div          style="            display: inline-block;            font-weight: bold;            font-size: 22px;            padding: 4px 40px;            border-radius: 20px;            background-color: #f2f2f2;          "          id="verify_code"        >          &{code}        </div>      </div>      <div>        如果您没有通过登录验证自己请求此代码，请更改您的密码。如果您需要支持，请联系我们。      </div>      <br />      <div>谢谢您让我们帮助您保管帐户。</div>      <br />      <br />      <div>祝你使用 XXX系统愉快,</div>      <div>XXX 团队</div>      <div style="margin: 20px 0"><hr /></div>      <div>        此通知已发送到与您的xxx帐户关联的电子邮件地址。      </div>      <div>此邮件是自动生成的，请不要回复。</div>      <div>        如果您需要其他帮助，请访问XXX系统支持。      </div>      <p style="text-align: center">        <a          href=&{domainUrl}          style="font-weight: bold; color: black"        >          &{domainUrl}        </a>      </p>    </div>
     * @return 请求体
     */
    public String buildEmailContent(String domainUrl, String logoUrl, String code, String content) {
        content = HtmlUtils.htmlUnescape(content);
        content = content.replace("&{logoUrl}", logoUrl);
        content = content.replace("&{code}", code);
        content = content.replace("&{domainUrl}", domainUrl);
        return content;
    }
}
